package com.trade.module.base.controller;

import com.trade.module.base.entity.Resource;
import com.trade.module.base.entity.User;
import com.trade.module.base.service.ResourceService;
import com.trade.system.security.SpringSessionRegistry;
import com.trade.module.base.service.LoginLogService;
import com.trade.module.base.service.UserService;
import com.trade.common.utils.*;
import com.trade.module.base.vo.UserVo;
import lombok.extern.log4j.Log4j;
import net.sf.json.JSONObject;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Class Description:
 *
 * @Version v1.0 2017/4/22 17:49
 * @JDK version 1.8.0_51
 * @Author zfb
 */
@Log4j
@Controller
public class HomeController extends BaseController {

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private UserService userService;
    @Autowired
    private LoginLogService loginLogService;

    /**
     * session管理
     */
    @Autowired
    private SpringSessionRegistry sessionRegistry;

    /**
     * 对项目跟路径的访问需要判断用户怒是否已经登录，如果用户已经登录则跳转至index页面，
     * 否则跳转至login页面
     *
     * @param request  请求
     * @param response 响应
     */
    @RequestMapping(value = "/")
    public void index(HttpServletRequest request, HttpServletResponse response) {
        UserVo user = getCurrentUser();
        if (user != null) {
            try {
                request.getRequestDispatcher("/index").forward(request, response);
            } catch (ServletException | IOException e) {
                e.printStackTrace();
            }
        } else {
            try {
                request.getRequestDispatcher("/login").forward(request, response);
            } catch (ServletException | IOException e) {
                e.printStackTrace();
            }

        }
    }

    @RequestMapping(value = "/index")
    public String home() {
        UserVo user = getCurrentUser();
        if (user != null) {
            return "/index";
        } else {
            return "/login";
        }
    }

    @RequestMapping(value = "/login")
    public String login() {
        UserVo user = getCurrentUser();
        if (user != null) {
            return "/index";
        } else {
            return "/login";
        }
    }

    /**
     * 拒绝访问
     */
    @RequestMapping(value = "/503")
    public String denied() {
        UserVo userVo = getCurrentUser();
        if (userVo != null) {
            return "/503";
        } else {
            return "/login";
        }
    }

    /**
     * 退出系统访问链接
     */
    @RequestMapping(value = "/mylogout")
    public String myLogout() {
        Object userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (null != userDetails && !Constants.ANONYMOUS_USER.equals(userDetails)) {
            User authUser = (User) userDetails;
            List<SessionInformation> sis = this.sessionRegistry.getAllSessions(authUser, false);
            if (sis != null) {
                for (SessionInformation si : sis) {
                    si.expireNow();
                    if (si.isExpired()) {
                        this.sessionRegistry.removeSessionInformation(si.getSessionId());
                    }
                }
            }
            logs.info("用户（" + authUser.getAccount() + "）登出系统！");
            return "redirect:/logout";
        } else {
            return "/login";
        }
    }


    @RequestMapping(value = "/oauth2login")
    public String oauth2login(HttpServletRequest request, HttpServletResponse response) {
        response.setHeader("Content-Type", "*/*; charset=UTF-8");
        //获取工程路径
        String sysBaseUrl = AppConfigurer.getProperties("baseurl");
        String code = request.getParameter("code");
        String clientId = request.getParameter("client_id");
        String accessToken = "0";
        String redirectUrl = "/index";
        if (Constants.BASE_CLIENTID.equalsIgnoreCase(clientId)) {
            String url = sysBaseUrl + "/oauth/token?grant_type=authorization_code&code=" + code + "&client_id="
                    + Constants.BASE_CLIENTID + "&client_secret=" + Constants.TRADE_CLIENTSECRET
                    + "&redirect_uri=" + sysBaseUrl + "/oauth2login?client_id=" + Constants.BASE_CLIENTID;
            redirectUrl = "/index";
            log.info("客户端编号与系统配置一致，编号：" + clientId);
            accessToken = getAccessToken(url);
        } else {
            redirectUrl = "/logout";
            accessToken = "";
        }
        //如果获取到的accessToken可用，将accessToken记录到session中
        if (XaUtil.isNotEmpty(accessToken)) {
            log.info("获取token成功，token=" + accessToken);
            request.getSession().setAttribute(Constants.CURRENTTOKEN_KEY_IN_SESSION, accessToken);
            request.getSession().setAttribute(Constants.CURRENTPLATFORM_KEY_IN_SESSION, clientId);
            //跳转到首页
            return "redirect:" + redirectUrl;
        } else {
            log.error("获取token失败，token=" + accessToken);
            //退出系统
            return "redirect:/logout";
        }
    }

    /**
     * Method description：查询当前登录用户的token
     * Version:V1.0
     * Author:lsk
     * Date:2016.05.10
     *
     * @return ResponseBean<String>
     */
    @ResponseBody
    @RequestMapping(value = "/getCurrentToken", method = RequestMethod.POST)
    public ResponseBean<String> getCurrentToken(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String accessToken = (String) session.getAttribute(Constants.CURRENTTOKEN_KEY_IN_SESSION);
        //打印日志，设置返回值
        if (XaUtil.isNotEmpty(accessToken)) {
            log.info("登录用户已认证，" + "sessionId=" + session.getId() + "   token=" + accessToken);
            return new ResponseBean<String>(ResponseUtil.SELECT_OK_200, "token有效", accessToken);
        } else {
            log.info("登录用户未进行认证，" + "sessionId=" + session.getId() + "   token=" + accessToken);
            return new ResponseBean<String>(ResponseUtil.NOT_EXIST_ERROR_404, "token无效", "0");
        }
    }

    /**
     * 通过模拟发送http请求获取accessToken
     *
     * @param url:获取tooken的访问地址
     */
    private static String getAccessToken(String url) {
        log.info("获取token的URL：" + url);
        String result = null;
        try {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            List<NameValuePair> nvps = new ArrayList<>();
            httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            log.info("开始执行获取token的http请求....");
            CloseableHttpResponse httpresponse = httpclient.execute(httpPost);
            log.info("执行获取token的http请求完成....httpresponse=" + httpresponse);
            result = EntityUtils.toString(httpresponse.getEntity());
            httpclient.close();
            httpresponse.close();
            JSONObject obj = JSONObject.fromObject(result);
            log.info("执行获取token的http请求结果：" + obj.toString());
            result = obj.getString("access_token");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

    /**
     * 客户端通过jsonp方式获取token
     *
     * @param request  請求
     * @param response 響應
     */
    @ResponseBody
    @RequestMapping(value = "/generateAccessToken", method = RequestMethod.GET)
    public void generateAccessToken(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("application/javascript");
        String backString = "";
        String callbackMethod = request.getParameter("callback");
        HttpSession session = request.getSession();

        String accessToken = (String) session.getAttribute(Constants.CURRENTTOKEN_KEY_IN_SESSION);
        System.out.println("generateMethod sessionid=" + session.getId() + "      access_tonken=" + accessToken);
        if (XaUtil.isNotEmpty(accessToken)) {
            // 查询用户资源信息
            String clientId = request.getParameter("clientId");
            UserVo user = getCurrentUser();
            // 查询用户资源信息
            List<Resource> resList = resourceService.reslistForClient(user.getId(), NetUtil.getIp(request));
            JSONObject resultObj = new JSONObject();
            resultObj.put("accessToken", accessToken);
            resultObj.put("user", user);
            resultObj.put("resList", resList);

            backString = UrlParamFilter.HTMLEncode(callbackMethod) + "(" + resultObj.toString() + ")";
        } else {
            backString = UrlParamFilter.HTMLEncode(callbackMethod) + "()";
        }

        log.info("返回用户信息为： " + backString);

        try {
            PrintWriter out = response.getWriter();
            out.println(backString);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //return backString;
    }
}
